package com.marketing.tenant.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.marketing.common.Result;
import com.marketing.tenant.annotation.RequirePermission;
import com.marketing.tenant.entity.TenantSubscription;
import com.marketing.tenant.service.TenantSubscriptionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 租户订阅管理控制器
 * 
 * @author Marketing System
 * @since 2024-09-25
 */
@RestController
@RequestMapping("/api/tenant-subscriptions")
@Validated
@Tag(name = "租户订阅管理", description = "租户订阅、续费、升级、降级等操作")
public class TenantSubscriptionController {
    
    private static final Logger log = LoggerFactory.getLogger(TenantSubscriptionController.class);
    
    @Autowired
    private TenantSubscriptionService subscriptionService;
    
    @PostMapping("/subscribe")
    @Operation(summary = "订阅计划", description = "租户订阅指定的计划")
    @RequirePermission("subscription:tenant:create")
    public Result<TenantSubscription> subscribePlan(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId,
            @Parameter(description = "计划ID") @RequestParam @NotNull @Min(1) Long planId,
            @Parameter(description = "订阅月数") @RequestParam @NotNull @Min(1) Integer months) {
        try {
            TenantSubscription subscription = subscriptionService.subscribePlan(tenantId, planId, months);
            return Result.success(subscription, "订阅成功");
        } catch (Exception e) {
            log.error("订阅失败: {}", e.getMessage(), e);
            return Result.error("订阅失败: " + e.getMessage());
        }
    }
    
    @PutMapping("/renew")
    @Operation(summary = "续费订阅", description = "为租户的当前订阅续费")
    @RequirePermission("subscription:tenant:update")
    public Result<String> renewSubscription(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId,
            @Parameter(description = "续费月数") @RequestParam @NotNull @Min(1) Integer months) {
        try {
            boolean success = subscriptionService.renewSubscription(tenantId, months);
            if (success) {
                return Result.success("续费成功");
            } else {
                return Result.error("续费失败");
            }
        } catch (Exception e) {
            log.error("续费失败: {}", e.getMessage(), e);
            return Result.error("续费失败: " + e.getMessage());
        }
    }
    
    @PutMapping("/upgrade")
    @Operation(summary = "升级订阅", description = "升级租户的订阅计划")
    @RequirePermission("subscription:tenant:update")
    public Result<String> upgradeSubscription(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId,
            @Parameter(description = "新计划ID") @RequestParam @NotNull @Min(1) Long newPlanId) {
        try {
            boolean success = subscriptionService.upgradeSubscription(tenantId, newPlanId);
            if (success) {
                return Result.success("升级成功");
            } else {
                return Result.error("升级失败");
            }
        } catch (Exception e) {
            log.error("升级失败: {}", e.getMessage(), e);
            return Result.error("升级失败: " + e.getMessage());
        }
    }
    
    @PutMapping("/downgrade")
    @Operation(summary = "降级订阅", description = "降级租户的订阅计划")
    @RequirePermission("subscription:tenant:update")
    public Result<String> downgradeSubscription(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId,
            @Parameter(description = "新计划ID") @RequestParam @NotNull @Min(1) Long newPlanId) {
        try {
            boolean success = subscriptionService.downgradeSubscription(tenantId, newPlanId);
            if (success) {
                return Result.success("降级成功");
            } else {
                return Result.error("降级失败");
            }
        } catch (Exception e) {
            log.error("降级失败: {}", e.getMessage(), e);
            return Result.error("降级失败: " + e.getMessage());
        }
    }
    
    @PutMapping("/cancel")
    @Operation(summary = "取消订阅", description = "取消租户的当前订阅")
    @RequirePermission("subscription:tenant:update")
    public Result<String> cancelSubscription(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId) {
        try {
            boolean success = subscriptionService.cancelSubscription(tenantId);
            if (success) {
                return Result.success("取消订阅成功");
            } else {
                return Result.error("取消订阅失败");
            }
        } catch (Exception e) {
            log.error("取消订阅失败: {}", e.getMessage(), e);
            return Result.error("取消订阅失败: " + e.getMessage());
        }
    }
    
    @PutMapping("/pause")
    @Operation(summary = "暂停订阅", description = "暂停租户的当前订阅")
    @RequirePermission("subscription:tenant:update")
    public Result<String> pauseSubscription(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId) {
        try {
            boolean success = subscriptionService.pauseSubscription(tenantId);
            if (success) {
                return Result.success("暂停订阅成功");
            } else {
                return Result.error("暂停订阅失败");
            }
        } catch (Exception e) {
            log.error("暂停订阅失败: {}", e.getMessage(), e);
            return Result.error("暂停订阅失败: " + e.getMessage());
        }
    }
    
    @PutMapping("/resume")
    @Operation(summary = "恢复订阅", description = "恢复租户的暂停订阅")
    @RequirePermission("subscription:tenant:update")
    public Result<String> resumeSubscription(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId) {
        try {
            boolean success = subscriptionService.resumeSubscription(tenantId);
            if (success) {
                return Result.success("恢复订阅成功");
            } else {
                return Result.error("恢复订阅失败");
            }
        } catch (Exception e) {
            log.error("恢复订阅失败: {}", e.getMessage(), e);
            return Result.error("恢复订阅失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/current")
    @Operation(summary = "获取当前订阅", description = "获取租户的当前有效订阅")
    @RequirePermission("subscription:tenant:read")
    public Result<TenantSubscription> getCurrentSubscription(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId) {
        try {
            TenantSubscription subscription = subscriptionService.getCurrentSubscription(tenantId);
            if (subscription != null) {
                return Result.success(subscription, "获取当前订阅成功");
            } else {
                return Result.error("没有找到有效订阅");
            }
        } catch (Exception e) {
            log.error("获取当前订阅失败: {}", e.getMessage(), e);
            return Result.error("获取当前订阅失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/history")
    @Operation(summary = "获取订阅历史", description = "分页获取租户的订阅历史记录")
    @RequirePermission("subscription:tenant:read")
    public Result<IPage<TenantSubscription>> getSubscriptionHistory(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId,
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") @Min(1) Integer page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") @Min(1) Integer size) {
        try {
            Page<TenantSubscription> pageParam = new Page<>(page, size);
            IPage<TenantSubscription> result = subscriptionService.getSubscriptionHistory(pageParam, tenantId);
            return Result.success(result, "获取订阅历史成功");
        } catch (Exception e) {
            log.error("获取订阅历史失败: {}", e.getMessage(), e);
            return Result.error("获取订阅历史失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/expiring")
    @Operation(summary = "获取即将到期订阅", description = "获取即将到期的订阅列表（7天内到期）")
    @RequirePermission("subscription:tenant:read")
    public Result<List<TenantSubscription>> getExpiringSubscriptions() {
        try {
            List<TenantSubscription> subscriptions = subscriptionService.getExpiringSubscriptions();
            return Result.success(subscriptions, "获取即将到期订阅成功");
        } catch (Exception e) {
            log.error("获取即将到期订阅失败: {}", e.getMessage(), e);
            return Result.error("获取即将到期订阅失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/expired")
    @Operation(summary = "获取已过期订阅", description = "获取已过期的订阅列表")
    @RequirePermission("subscription:tenant:read")
    public Result<List<TenantSubscription>> getExpiredSubscriptions() {
        try {
            List<TenantSubscription> subscriptions = subscriptionService.getExpiredSubscriptions();
            return Result.success(subscriptions, "获取已过期订阅成功");
        } catch (Exception e) {
            log.error("获取已过期订阅失败: {}", e.getMessage(), e);
            return Result.error("获取已过期订阅失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/process-expired")
    @Operation(summary = "处理过期订阅", description = "批量处理过期订阅，更新状态")
    @RequirePermission("subscription:tenant:update")
    public Result<Integer> processExpiredSubscriptions() {
        try {
            int count = subscriptionService.processExpiredSubscriptions();
            return Result.success(count, "处理过期订阅成功，处理数量: " + count);
        } catch (Exception e) {
            log.error("处理过期订阅失败: {}", e.getMessage(), e);
            return Result.error("处理过期订阅失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/has-active")
    @Operation(summary = "检查有效订阅", description = "检查租户是否有有效订阅")
    @RequirePermission("subscription:tenant:read")
    public Result<Boolean> hasActiveSubscription(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId) {
        try {
            boolean hasActive = subscriptionService.hasActiveSubscription(tenantId);
            return Result.success(hasActive, "检查完成");
        } catch (Exception e) {
            log.error("检查有效订阅失败: {}", e.getMessage(), e);
            return Result.error("检查有效订阅失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/feature-access")
    @Operation(summary = "检查功能权限", description = "检查租户是否有指定功能的访问权限")
    @RequirePermission("subscription:tenant:read")
    public Result<Boolean> hasFeatureAccess(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId,
            @Parameter(description = "功能名称") @RequestParam String feature) {
        try {
            boolean hasAccess = subscriptionService.hasFeatureAccess(tenantId, feature);
            return Result.success(hasAccess, "检查完成");
        } catch (Exception e) {
            log.error("检查功能权限失败: {}", e.getMessage(), e);
            return Result.error("检查功能权限失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/usage-limit")
    @Operation(summary = "获取使用限制", description = "获取租户的使用限制信息")
    @RequirePermission("subscription:tenant:read")
    public Result<Integer> getUsageLimit(
            @Parameter(description = "租户ID") @RequestParam @NotNull @Min(1) Long tenantId,
            @Parameter(description = "限制类型") @RequestParam String limitType) {
        try {
            Integer limit = subscriptionService.getUsageLimit(tenantId, limitType);
            return Result.success(limit, "获取使用限制成功");
        } catch (Exception e) {
            log.error("获取使用限制失败: {}", e.getMessage(), e);
            return Result.error("获取使用限制失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/stats")
    @Operation(summary = "获取订阅统计", description = "获取订阅数据统计信息")
    @RequirePermission("subscription:tenant:read")
    public Result<Object> getSubscriptionStats(
            @Parameter(description = "计划ID（可选）") @RequestParam(required = false) Long planId,
            @Parameter(description = "开始时间") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startDate,
            @Parameter(description = "结束时间") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endDate) {
        try {
            Object stats = subscriptionService.getSubscriptionStats(planId, startDate, endDate);
            return Result.success(stats, "获取订阅统计成功");
        } catch (Exception e) {
            log.error("获取订阅统计失败: {}", e.getMessage(), e);
            return Result.error("获取订阅统计失败: " + e.getMessage());
        }
    }
}